package org.xshop.service.impl;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

import org.apache.commons.lang3.RandomUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.xshop.BizConstants.TradeStyle;
import org.xshop.mapper.TExpressmanTradeMapper;
import org.xshop.model.TExpressman;
import org.xshop.model.TExpressmanAccount;
import org.xshop.model.TExpressmanTrade;
import org.xshop.service.ITExpressmanTradeService;

import com.alipay.api.AlipayApiException;
import com.alipay.api.domain.AlipayFundTransToaccountTransferModel;
import com.baomidou.mybatisplus.toolkit.IdWorker;
import com.weibo.api.motan.config.springsupport.annotation.MotanService;

import top.ibase4j.core.base.BaseServiceImpl;
import top.ibase4j.core.exception.BusinessException;
import top.ibase4j.core.support.generator.Sequence;
import top.ibase4j.core.support.pay.AliPay;
import top.ibase4j.core.support.pay.WxPay;
import top.ibase4j.core.support.pay.WxPayment;
import top.ibase4j.core.util.CacheUtil;
import top.ibase4j.core.util.DateUtil;
import top.ibase4j.core.util.InstanceUtil;
import top.ibase4j.core.util.PropertiesUtil;

/**
 * <p>
 * 骑手收入明细 服务实现类
 * </p>
 *
 * @author ShenHuaJie
 * @since 2018-05-30
 */
@MotanService(interfaceClass = ITExpressmanTradeService.class)
@CacheConfig(cacheNames = "TExpressmanTrade")
public class ExpressmanTradeService extends BaseServiceImpl<TExpressmanTrade, TExpressmanTradeMapper>
implements ITExpressmanTradeService {
    @Autowired
    private ExpressmanService expressmanService;
    @Autowired
    private ExpressmanAccountService expressmanAccountService;

    @Override
    public void trade(TExpressmanTrade param) {
        String key = "EXPRESS-MONEY-" + param.getExpressmanId();
        String requestId = Sequence.next().toString();
        if (CacheUtil.getLock(key, requestId)) {
            try {
                TExpressman expressman = expressmanService.queryById(param.getExpressmanId());
                if (param.getTradeMoney().doubleValue() > expressman.getMoney().doubleValue()) {
                    throw new BusinessException("余额不足");
                }
                String orderNo = "E" + DateUtil.format(new Date(), "yyyyMMddHHmmss") + param.getExpressmanId()
                + RandomUtils.nextInt(100, 999);
                param.setTradeOrderNo(orderNo);
                //
                TExpressmanAccount account = expressmanAccountService.queryById(param.getAccountId());
                if (TradeStyle.WECHAT.toString().equals(account.getAccountType())) {
                    try {
                        param.setRemark("微信提现至" + account.getAccountNo());
                        Map<String, String> params = InstanceUtil.newHashMap();
                        params.put("mch_appid", PropertiesUtil.getString("wx.appId"));
                        params.put("mchid", PropertiesUtil.getString("wx.mch_id"));
                        params.put("nonce_str", IdWorker.get32UUID());
                        params.put("partner_trade_no", param.getTradeOrderNo());
                        params.put("openid", account.getOpenid());
                        params.put("check_name", "FORCE_CHECK");
                        params.put("re_user_name", expressman.getUserName());
                        params.put("amount", param.getTradeMoney().multiply(new BigDecimal("100")).toString());
                        params.put("desc", expressman.getPhone() + "提现");
                        params.put("spbill_create_ip", param.getClientIP());

                        String sign = WxPayment.createSign(params, PropertiesUtil.getString("wx.partnerKey"));
                        params.put("sign", sign);
                        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
                        String path = resolver.getResources(PropertiesUtil.getString("wx.certPath"))[0].getFile()
                                .getAbsolutePath();
                        String result = WxPay.transfers(params, path, PropertiesUtil.getString("wx.certPass"));
                        logger.info("WeChart order result : " + result);
                        Map<String, String> resultMap = WxPayment.xmlToMap(result);
                        String return_code = resultMap.get("return_code");
                        if (WxPayment.codeIsOK(return_code)) {
                            String result_code = resultMap.get("result_code");
                            if (WxPayment.codeIsOK(result_code)) {

                            } else {
                                throw new RuntimeException(resultMap.get("err_code_des"));
                            }
                        } else {
                            throw new RuntimeException(resultMap.get("return_msg"));
                        }
                    } catch (IOException e) {
                        throw new RuntimeException("提现失败", e);
                    }
                } else if (TradeStyle.ALIPAY.toString().equals(account.getAccountType())) {
                    param.setRemark("支付宝提现至" + account.getAccountNo());
                    AlipayFundTransToaccountTransferModel model = new AlipayFundTransToaccountTransferModel();
                    model.setOutBizNo(param.getTradeOrderNo());
                    model.setAmount(param.getTradeMoney().toString());
                    model.setPayeeType("ALIPAY_LOGONID");
                    model.setPayeeAccount(account.getAccountNo());
                    model.setRemark(expressman.getPhone() + "提现");
                    try {
                        if (!AliPay.transfer(model)) {
                            throw new BusinessException("提现失败");
                        }
                    } catch (AlipayApiException e) {
                        throw new RuntimeException("提现失败", e);
                    }
                }
                expressman.setMoney(expressman.getMoney().subtract(param.getTradeMoney()));
                expressmanService.update(expressman);
                param.setTradeType("2");
                param.setCreateBy(param.getExpressmanId());
                super.update(param);
            } finally {
                CacheUtil.unLock(key, requestId);
            }
        }
    }

    @Override
    public BigDecimal getSumMoney(Map<String, Object> params) {
        return mapper.getSumMoney(params);
    }
}
